from fastapi.routing import APIRoute
from fastapi import Depends

from app.auth.handlers.auth_ldap_handler import AuthLdapHandler
from app.auth.models.auth_users import AuthUsers
from app.auth.models.auth_roles import AuthRoles
from app.auth.models.auth_permissions import AuthPermissions
from common.utils import random_generator
from common.database import SessionLocal
from core.security import security
from common.redispy import redispy
from core.security import permission_checker

from setting import config
from main import app
from core.logger import logger

__all__ = ['AuthClick']


class AuthClick(object):
    def __init__(self):
        self.session = SessionLocal()

    def __del__(self):
        self.session.close()

    def user_info_sync_from_ldap(self):
        """
        同步LDAP用户信息到数据库
        """
        auth_ldap_handler = AuthLdapHandler()
        for data in auth_ldap_handler.get_users():
            password = random_generator()
            user = AuthUsers.add(self.session, {'username': data.get('username'), 'nick_name': data.get('username'), 'auth_type': 'ldap',
                                                'email': data.get('mail'), 'mobile': data.get('mobile'),
                                                'hash_password': security.create_password_hash(password), 'is_superuser': False,
                                                'is_active': True})

    # 创建admin用户
    def auth_create_role_admin(self):
        role = self.session.query(AuthRoles).filter(AuthRoles.role_name == 'admin').first()
        if not role:
            role = AuthRoles.add(self.session, {'role_name': 'admin', 'description': '系统管理员'})
        role.auth_permissions = self.session.query(AuthPermissions).all()
        self.session.commit()

    def auth_create_account_admin(self):
        role = self.session.query(AuthRoles).filter(AuthRoles.role_name == 'admin').first()
        if not role:
            return {}
        password = random_generator()
        hash_password = security.create_password_hash(password)
        user = self.session.query(AuthUsers).filter(AuthUsers.username == 'admin').first()
        if not user:
            user = AuthUsers.add(self.session, {'username': 'admin', 'nick_name': 'admin', 'auth_type': 'mysql',
                                                'email': 'admin@welab-inc.com', 'mobile': '',
                                                'hash_password': hash_password,
                                                'is_superuser': True, 'is_active': True})
        else:
            user.hash_password = hash_password
        user.auth_roles = self.session.query(AuthRoles).filter(AuthRoles.uuid == role.uuid).all()
        self.session.commit()
        return {"admin": password}



    # 创建普通用户的角色
    def auth_create_role(self, account_name):
        role = self.session.query(AuthRoles).filter(AuthRoles.role_name == account_name).first()
        if role:
            logger.info(f"role:{account_name} already exists")
            return role
        
        role = AuthRoles.add(self.session, {'role_name': account_name, 'description': '命令行创建账号'})
        if not role:
            logger.error(f"role:{account_name} create failed")
            return None
        logger.info(f"role:{account_name} create success")
        return role


    # 创建普通用户
    def auth_create_account(self, account_name):
        # 创角色
        role = self.auth_create_role(account_name)
        if not role:
            logger.error(f"auth create role failed")
            return False
            
        # 创建账号
        password = random_generator()
        hash_password = security.create_password_hash(password)
        user = self.session.query(AuthUsers).filter(AuthUsers.username == account_name).first()
        if not user:
            # 用户不存在，则创建
            user = AuthUsers.add(self.session, {'username': account_name, 'nick_name': account_name, 'auth_type': 'mysql',
                                                'email': f'{account_name}@welab-inc.com', 'mobile': '',
                                                'hash_password': hash_password,
                                                'is_superuser': False, 'is_active': True})
            if not user:
                logger.error(f"auth create user failed")
                return False
            logger.info(f"account:{account_name} create success")
        else:
            # 用户已存在，清理redis里面之前的token
            redispy.clean_token(account_name)
            logger.info(f"account:{account_name} already exists")

        # 更新账号信息
        user.hash_password = hash_password
        user.auth_roles = self.session.query(AuthRoles).filter(AuthRoles.uuid == role.uuid).all()
        self.session.commit()
        logger.info(f"account:{account_name} update info success")
        
        # 创建token
        data = {"uuid": user.uuid, "username": user.username, "avatar": user.avatar, "is_active": user.is_active, "is_superuser": user.is_superuser}
        token = security.create_access_token(data)
        logger.info(f"account:{account_name} create token success")
        
        return {"name": account_name, "password": password, "token": token}



    def auth_update_permissions(self):
        for route in app.routes:
            if isinstance(route, APIRoute):
                if route.path in ["/ops/api/v1/login", "/ops/api/v1/user/info"]:
                    continue
                
                data = {"permission_name": route.name, "method": list(route.methods)[0].lower(),
                            "url": route.path, "tags": list(route.tags)[0].lower(),
                            "summary": route.summary, "description": route.description}
                permissions_info = AuthPermissions.get_by_permission_name(self.session, route.name)
                if not permissions_info:
                    # 如果不存在则添加
                    AuthPermissions.add(self.session, data)
                    logger.info(f"permission_name:{route.name} add success")
                else:
                    # 如果存在则更新
                    data["uuid"] = permissions_info["uuid"]
                    AuthPermissions.update(self.session, data)
                    logger.info(f"permission_name:{route.name} update success")
        
        return True
    
    
    
    def auth_check_permissions(self):
        for route in app.routes:
            if isinstance(route, APIRoute):
                if route.path in ["/ops/api/v1/login", "/ops/api/v1/user/info"]:
                    continue
                
                if route.name == "get_bill_instance_aliyun":
                    print("aaa")
                for depend_object in route.dependant.dependencies:
                    depend_str = str(depend_object)
                    if depend_object.name == "user":
                        break
                else:
                    logger.info(f"name:{route.name} ")

def main():
    auth_click = AuthClick()

    # auth_click.user_info_sync_from_ldap()
    # auth_click.create_admin_role()
    # auth_click.auth_create_account("yunwei-api")
    # auth_click.auth_update_permissions()
    auth_click.auth_check_permissions()


if __name__ == "__main__":
    main()
